package pixelradar.entities;

import com.pixelmonmod.pixelmon.Pixelmon;
import com.pixelmonmod.pixelmon.blocks.enums.EnumPokeChestType;
import com.pixelmonmod.pixelmon.blocks.enums.EnumPokechestVisibility;
import com.pixelmonmod.pixelmon.blocks.tileEntities.*;
import com.pixelmonmod.pixelmon.entities.EntityDen;
import com.pixelmonmod.pixelmon.entities.npcs.EntityNPC;
import com.pixelmonmod.pixelmon.entities.npcs.NPCTrainer;
import com.pixelmonmod.pixelmon.entities.pixelmon.EntityPixelmon;
import com.pixelmonmod.pixelmon.entities.pixelmon.EntityStatue;
import com.pixelmonmod.pixelmon.enums.EnumBossMode;
import com.pixelmonmod.pixelmon.enums.EnumGrowth;
import com.pixelmonmod.pixelmon.enums.EnumSpecies;
import com.pixelmonmod.pixelmon.enums.forms.IEnumForm;
import com.pixelmonmod.pixelmon.pokedex.Pokedex;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import pixelradar.config.PokeradarConfig;
import pixelradar.gui.RadarGui;
import pixelradar.map.MapRenderer;
import pixelradar.map.PKMarker;
import pixelradar.util.Reference;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class EntityFinder {
    public static List<PKMarker> pkMarkers = new ArrayList<>();

    public static void getAndDraw(MapRenderer mp, Minecraft mc) {
        if (mc.world != null && mc.world.getLoadedEntityList().size() > 1) {
            List<Entity> entityList = mc.world.loadedEntityList;
            List<TileEntity> tileList = mc.world.loadedTileEntityList;
            addEntityList(entityList, mp, mc);
            addTileList(tileList, mp, mc);
        }

    }

    public static void addEntityList(List<Entity> entityList, MapRenderer mp, Minecraft mc) {
        for (Entity entity : entityList) {
            if (entity instanceof EntityPixelmon) {
                EntityPixelmon pixelmon = (EntityPixelmon) entity;
                if (pixelmon.getOwner() != null && !PokeradarConfig.drawPlayerPixelmonLines) {
                    continue;
                }
                EnumBossMode bossMode = pixelmon.getBossMode();
                EntityType type = EntityType.REGULAR;
                String desc = "";
                String localizedName = pixelmon.getLocalizedName();
                if (pixelmon.isBossPokemon()) {
                    if (bossMode != EnumBossMode.NotBoss) {
                        switch (bossMode) {
                            case Uncommon:
                                type = EntityType.BOSS_UNCOMMON;
                                break;
                            case Rare:
                                type = EntityType.BOSS_RARE;
                                break;
                            case Epic:
                                type = EntityType.BOSS_EPIC;
                                break;
                            case Legendary:
                                type = EntityType.BOSS_LEGENDARY;
                                break;
                            case Ultimate:
                                type = EntityType.BOSS_ULTIMATE;
                                break;
                            case Spooky:
                                type = EntityType.BOSS_SPOOKY;
                                break;
                            case Drowned:
                                type = EntityType.BOSS_DROWNED;
                                break;
                            case Equal:
                                type = EntityType.BOSS_EQUAL;
                                break;
                            default:
                                type = EntityType.BOSS_COMMON;
                        }
                        desc = bossMode.getLocalizedName();
                    }
                } else if (Reference.LEGENDARIES.contains(pixelmon.getSpecies().name)) {
                    type = EntityType.LEGENDARY;
                    desc = I18n.format("mw.finder.msg.legendary") + " ";
                } else if (Reference.ULTRA_BEASTS.contains(pixelmon.getSpecies().name)) {
                    type = EntityType.ULTRA_BEAST;
                    desc = I18n.format("mw.finder.msg.ultra_beast") + " ";
                } else if (Reference.DITTOS.contains(pixelmon.getSpecies().name)) {
                    type = EntityType.DITTO;
                    desc = I18n.format("mw.finder.msg.ditto") + " ";
                } else {
                    IEnumForm form = pixelmon.getPokemonData().getFormEnum();
                    boolean isShiny = pixelmon.getPokemonData().isShiny();
                    String nameLower = pixelmon.getSpecies().name.toLowerCase();
                    boolean foundForm;
                    if (isShiny) {
                        type = EntityType.SHINY;
                    }
                    if (RadarGui.searchString != null) {
                        String lowerSearchString = RadarGui.searchString.replace("，", ",").toLowerCase();
                        String[] nameArr = lowerSearchString.split(",");
                        for (String s : nameArr) {
                            if (s.trim().length() >= 2 && (nameLower.contains(s.trim()) || localizedName.contains(s.trim()))) {
                                if (isShiny) {
                                    type = EntityType.SPECIAL;
                                } else {
                                    type = EntityType.SEARCHED;
                                }
                            }
                        }
                        if (mc.isSingleplayer() && (lowerSearchString.contains("pokedex") || lowerSearchString.contains(I18n.format("mw.finder.msg.dex")))) {
                            Pokedex playerDex = Pixelmon.storageManager.getParty(mc.player.getUniqueID()).pokedex;
                            Pokedex.loadPokedex();
                            if (!playerDex.hasCaught(EnumSpecies.getFromNameAnyCase(pixelmon.getSpecies().name))) {
                                type = EntityType.DEX;
                                desc = I18n.format("mw.finder.msg.missingDex") + " ";
                            }
                        }
                    }
                    if (RadarGui.getGrowth() != null) {
                        foundForm = false;
                        if (pixelmon.getPokemonData().getGrowth().index == 8 && RadarGui.getGrowth().equals(EnumGrowth.Microscopic)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 0 && RadarGui.getGrowth().equals(EnumGrowth.Pygmy)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 1 && RadarGui.getGrowth().equals(EnumGrowth.Runt)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 2 && RadarGui.getGrowth().equals(EnumGrowth.Small)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 3 && RadarGui.getGrowth().equals(EnumGrowth.Ordinary)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 4 && RadarGui.getGrowth().equals(EnumGrowth.Huge)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 5 && RadarGui.getGrowth().equals(EnumGrowth.Giant)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 6 && RadarGui.getGrowth().equals(EnumGrowth.Enormous)) {
                            foundForm = true;
                        } else if (pixelmon.getPokemonData().getGrowth().index == 7 && RadarGui.getGrowth().equals(EnumGrowth.Ginormous)) {
                            foundForm = true;
                        }
                        if (!foundForm) {
                            type = isShiny ? type : EntityType.REGULAR;
                        } else if (isShiny) {
                            type = EntityType.SPECIAL;
                        } else {
                            type = EntityType.SEARCHED;
                        }
                    }
                    if (RadarGui.getForm() != null) {
                        foundForm = RadarGui.getForm().getFormSuffix().equals(form.getFormSuffix());
                        if (!foundForm) {
                            type = isShiny ? type : EntityType.REGULAR;
                        } else if (isShiny) {
                            type = EntityType.SPECIAL;
                        } else {
                            type = EntityType.SEARCHED;
                        }
                    }
                }
                desc = desc + (desc.isEmpty() ? "" : " ") + "Lvl " + pixelmon.getPokemonData().getLevel();
                pkMarkers.add(new PKMarker(type, pixelmon, localizedName, desc, type.getRadius(), mp, mc.world.provider.getDimension()));
            }
            if (entity instanceof EntityOtherPlayerMP) {
                EntityOtherPlayerMP otherPlayer = (EntityOtherPlayerMP) entity;
                pkMarkers.add(new PKMarker(EntityType.PLAYER, otherPlayer, otherPlayer.getDisplayNameString(), I18n.format("mw.finder.msg.player"), EntityType.PLAYER.getRadius(), mp, mc.world.provider.getDimension()));
            }
            if (entity instanceof EntityStatue) {
                EntityStatue statue = (EntityStatue) entity;
                pkMarkers.add(new PKMarker(EntityType.STATUE, statue, statue.getSpecies().getLocalizedName(), " ", EntityType.STATUE.getRadius(), mp, mc.world.provider.getDimension()));
            }
            if (entity instanceof EntityNPC) {
                EntityNPC npc = (EntityNPC) entity;
                if (npc instanceof NPCTrainer) {
                    NPCTrainer trainer = (NPCTrainer) npc;
                    pkMarkers.add(new PKMarker(EntityType.NPC, trainer, I18n.format("mw.finder.msg.npcTrainer"), "Lvl: " + trainer.getBossMode().getLocalizedName(), EntityType.NPC.getRadius(), mp, mc.world.provider.getDimension()));
                } else {
                    pkMarkers.add(new PKMarker(EntityType.NPC, npc, I18n.format("mw.finder.msg.npc"), npc.getDisplayText(), EntityType.NPC.getRadius(), mp, mc.world.provider.getDimension()));
                }
            }
            if (entity instanceof EntityDen) {
                pkMarkers.add(new PKMarker(EntityType.WORMHOLE, entity, I18n.format("mw.finder.msg.wormhole"), " ", EntityType.WORMHOLE.getRadius(), mp, mc.world.provider.getDimension()));
            }
        }
    }

    private static void addTileList(List<TileEntity> tileList, MapRenderer mp, Minecraft mc) {

        for (TileEntity tileIt : tileList) {
            if (tileIt instanceof TileEntityPokeChest) {
                TileEntityPokeChest tile = (TileEntityPokeChest) tileIt;
                String desc;
                if (tile.getVisibility() == EnumPokechestVisibility.Hidden) {
                    desc = I18n.format("mw.finder.msg.loot.hidden");
                } else {
                    EnumPokeChestType chestType = tile.getType();
                    switch (chestType) {
                        case POKEBALL:
                            desc = I18n.format("mw.finder.msg.loot.tier1");
                            break;
                        case ULTRABALL:
                            desc = I18n.format("mw.finder.msg.loot.tier2");
                            break;
                        case MASTERBALL:
                            desc = I18n.format("mw.finder.msg.loot.tier3");
                            break;
                        case BEASTBALL:
                            desc = I18n.format("mw.finder.msg.loot.tier4");
                            break;
                        default:
                            desc = I18n.format("mw.finder.msg.loot.special");
                    }
                }
                pkMarkers.add(new PKMarker(EntityType.LOOT, tile, I18n.format("mw.finder.msg.loot"), desc, EntityType.LOOT.getRadius(), mp, mc.world.provider.getDimension()));
            } else if (tileIt instanceof TileEntityShrine) {
                addShrine(tileIt, TileEntityShrine.class, mp, mc);
            } else if (tileIt instanceof TileEntityTimespaceAltar) {
                addShrine(tileIt, TileEntityTimespaceAltar.class, mp, mc);
            } else if (tileIt instanceof TileEntityPlateHolder) {
                addShrine(tileIt, TileEntityPlateHolder.class, mp, mc);
            } else if (tileIt instanceof TileEntityIlexShrine) {
                addShrine(tileIt, TileEntityIlexShrine.class, mp, mc);
            } else if (tileIt instanceof TileEntityZygardeCell) {
                addGadget(tileIt, mp, mc);
            }
        }

    }

    private static void addShrine(TileEntity tile, Class<? extends TileEntity> clazz, MapRenderer mp, Minecraft
            mc) {
        TileEntity tileEntity = clazz.cast(tile);
        String type = Optional.of(tileEntity.getBlockType().getLocalizedName()).orElse("");
        pkMarkers.add(new PKMarker(EntityType.SHRINE, tileEntity, I18n.format("mw.finder.msg.shrine"), type, EntityType.SHRINE.getRadius(), mp, mc.world.provider.getDimension()));
    }

    private static void addGadget(TileEntity tile, MapRenderer mp, Minecraft mc) {
        TileEntity tileEntity = ((Class<? extends TileEntity>) TileEntityZygardeCell.class).cast(tile);
        String type = Optional.of(tileEntity.getBlockType().getLocalizedName()).orElse("");
        pkMarkers.add(new PKMarker(EntityType.GADGET, tileEntity, I18n.format("mw.finder.msg.gadget"), type, EntityType.GADGET.getRadius(), mp, mc.world.provider.getDimension()));
    }
}
